package com.zh.config.utils

import android.content.ContentResolver
import android.content.ContentValues
import android.content.Context
import android.media.MediaScannerConnection
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.os.FileUtils
import android.provider.MediaStore
import com.blankj.utilcode.util.ActivityUtils
import com.blankj.utilcode.util.AppUtils
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.Utils
import com.zh.common.base.BaseApplication
import com.zh.common.ktx.getMimeType
import com.zh.common.ktx.toast
import com.zh.common.utils.GetFilePathFromUri
import com.zh.common.utils.OpenFileUtil
import com.zh.config.db.DbDownloadHelper
import com.zh.config.db.DownEnum
import com.zh.config.db.DownloadDao
import java.io.File
import java.io.FileInputStream
import java.io.IOException
import java.io.OutputStream

/**
 * 需要引入FileDownLoader下载库
 * com.liulishuo.filedownloader:library:1.7.7
 */
class DownloadFileUtils {

//    private val downloadList = mutableListOf<Pair<Pair<String, Int>, BaseDownloadTask>>()
    val dbList = mutableListOf<DownloadDao>()
    val dbDownloadHelper by lazy { DbDownloadHelper(BaseApplication.instance.applicationContext) }
//    val callList = hashMapOf<String, BaseDownloadTask>()

    companion object {
        val instance by lazy {
//            FileDownloader.getImpl().setMaxNetworkThreadCount(3)
            DownloadFileUtils()
        }
    }

    //初始化全部下载
    fun init() {
        dbList.clear()
//        downloadList.clear()
//        callList.clear()
        dbDownloadHelper.getAllDownload()?.let { it.reverse();dbList.addAll(it) }
        dbList.forEach { dao ->
//            val task = FileDownloader.getImpl().create(dao.url).setPath(dao.filePath)
//            task.addFinishListener {
//                if (it.status == FileDownloadStatus.completed) {
//                    installApp(dao)
//                }
//            }
//            task.autoRetryTimes = 3
//            task.setMinIntervalUpdateSpeed(500)
//            task.isForceReDownload = true
//            downloadList.add(Pair(Pair(dao.url, dao.time), task))
//            callList[dao.url] = task
        }
    }

    //创建单个下载
    fun create(dao: DownloadDao) {
        if (dbList.any { it.url == dao.url }) {
            startTask(dao.url, dao.time)
        } else {
            dbList.add(0, dao)
            dbDownloadHelper.put(dao.url, dao)

//            val task = FileDownloader.getImpl().create(dao.url).setPath(dao.filePath)
//            task.addFinishListener {
//                if (it.status == FileDownloadStatus.completed) {
//                    installApp(dao)
//                }
//            }
//            task.autoRetryTimes = 3
//            task.setMinIntervalUpdateSpeed(500)
//            task.isForceReDownload = true
//            downloadList.add(0, Pair(Pair(dao.url, dao.time), task))
//            callList[dao.url] = task
        }
    }

//    fun hasTask(url: String): Boolean {
//        return downloadList.any { it.first.first == url }
//    }

    fun startTask(url: String, time: Int) {
//        try {
//            kotlin.run {
//                downloadList.forEachIndexed { index, it ->
//                    if (it.first.first == url && it.first.second == time) {
//                        if (it.second.isUsing) {
//                            it.second.reuse()
//                        }
//                        it.second.start()
//                        updateState(it.first, index, DownEnum.progress.state)
//                        return@run
//                    }
//                }
//            }
//        } catch (e: Exception) {
//            e.printStackTrace()
//        }
    }

    fun startAllTask() {
//        try {
//            downloadList.forEachIndexed { index, it ->
//                if (it.second.isUsing) {
//                    it.second.reuse()
//                }
//                it.second.start()
//                updateState(it.first, index, DownEnum.progress.state)
//            }
//        } catch (e: Exception) {
//            e.printStackTrace()
//        }
    }

    fun pauseTask(url: String, time: Int) {
//        try {
//            kotlin.run {
//                downloadList.forEachIndexed { index, it ->
//                    if (it.first.first == url && it.first.second == time) {
//                        it.second.pause()
//                        updateState(it.first, index, DownEnum.paused.state)
//                        return@run
//                    }
//                }
//            }
//        } catch (e: Exception) {
//            e.printStackTrace()
//        }
    }

    fun pauseAllTask() {
//        try {
//            downloadList.forEachIndexed { index, it ->
//                it.second.pause()
//                updateState(it.first, index, DownEnum.paused.state)
//            }
//        } catch (e: Exception) {
//            e.printStackTrace()
//        }
    }

    /*fun failTask(url: String) {
        try {
            kotlin.run {
                downloadList.forEachIndexed { index, it ->
                    if (it.first == url) {
                        updateState(it.first, index, DownEnum.error.state)
                        return@run
                    }
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }*/

    /*fun overTask(url: String) {
        try {
            kotlin.run {
                downloadList.forEachIndexed { index, it ->
                    if (it.first == url) {
                        updateState(it.first, index, DownEnum.completed.state)
                        return@run
                    }
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }*/

    //删除数据，同时删除数据库数据
    fun removeData(url: String, time: Int) {
        try {
//            kotlin.run {
//                downloadList.forEachIndexed { index, it ->
//                    if (it.first.first == url && it.first.second == time) {
//                        FileDownloader.getImpl().clear(it.second.id, "")
////                        FileDownloader.getImpl().clear(it.second.id, it.second.targetFilePath)
//                        downloadList.removeAt(index)
//                        return@run
//                    }
//                }
//            }
            kotlin.run {
                dbList.forEachIndexed { index, it ->
                    if (it.url == url && it.time == time) {
                        deleteFile(it.filePath)
                        dbList.removeAt(index)
                        return@run
                    }
                }
            }
            LogUtils.d("removeData", dbList.size)
            dbDownloadHelper.remove(url, time)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    fun removeAllData() {
//        try {
//            FileDownloader.getImpl().clearAllTaskData()
//            downloadList.clear()
//            dbList.forEach {
//                deleteFile(it.filePath)
//            }
//            dbList.clear()
//            dbDownloadHelper.removeAll()
//        } catch (e: Exception) {
//            e.printStackTrace()
//        }
    }

    private fun deleteFile(filePath: String) {
        try {
            val file = File(filePath)
            if (file.exists() && file.length() == 0L) {
                file.delete()
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    //0：准备，1：下载中，2：暂停，3：失败，4：完成，5：已删除
    private fun updateState(pair: Pair<String, Int>, index: Int, state: Int) {
        try {
            val dao = dbList[index]
            val dao2 = DownloadDao(
                dao.id, dao.url, dao.name, dao.logo, dao.filePath, state, dao.total, dao.time
            )
            dbList.removeAt(index)
            dbList.add(index, dao2)
            dbDownloadHelper.put(pair.first, dao2)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    private fun updateState(dao: DownloadDao, state: Int) {
        try {
            val dao2 = DownloadDao(
                dao.id, dao.url, dao.name, dao.logo, dao.filePath, state, dao.total, dao.time
            )
            dbDownloadHelper.put(dao.url, dao2)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    fun installApp(dao: DownloadDao, isOnlyOpen: Boolean = false) {
        try {
            if (dao.state != DownEnum.completed.state) {//修改状态
                updateState(dao, DownEnum.completed.state)
                val index = dbList.indexOfFirst { it.url == dao.url }
                dbList[index].state = DownEnum.completed.state
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        try {
            if (dao.filePath.endsWith(".apk")) {
                val file = File(dao.filePath)
                if (file.exists() && file.length() > 1000) {
                    AppUtils.installApp(dao.filePath)
                }
            } else {
                ActivityUtils.getTopActivity()?.let {
                    OpenFileUtil.openFile(it, dao.filePath)
                    if (!isOnlyOpen) {
                        notifyMedia(it, dao.filePath)
                    }
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    //通知图库
    private fun notifyMedia(context: Context, filePath: String) {
        try {
            val suffix = GetFilePathFromUri.getFileSuffix(filePath)
            if (KnowledgeType.isImage(suffix) || KnowledgeType.isVideo(suffix)) {
                val file = File(filePath)
                val mimeType = getMimeType(file)
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                    val fileName = file.name
                    val values = ContentValues()
                    values.put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
                    values.put(MediaStore.MediaColumns.MIME_TYPE, mimeType)
                    values.put(
                        MediaStore.MediaColumns.RELATIVE_PATH,
                        Environment.DIRECTORY_DCIM
                    )
                    val contentResolver: ContentResolver = context.contentResolver
                    val uri = contentResolver.insert(
                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values
                    )
                    if (uri == null) {
                        toast("保存失败")
                        return
                    }
                    try {
                        val out: OutputStream = contentResolver.openOutputStream(uri)!!
                        val fis = FileInputStream(file)
                        FileUtils.copy(fis, out)
                        fis.close()
                        out.close()
                        toast("保存成功")
                    } catch (e: IOException) {
                        e.printStackTrace()
                    }
                } else {
                    MediaScannerConnection.scanFile(
                        Utils.getApp(), arrayOf(file.path), arrayOf(mimeType)
                    ) { path: String, uri: Uri? ->
                        toast("保存成功")
                    }
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
}